package com.jykj.modbus.equipment.service;

import com.jykj.modbus.equipment.entity.ReturnModBus;
import com.jykj.modbus.equipment.entity.guard.Equipment;
import com.jykj.modbus.equipment.entity.guard.EquipmentData;
import com.jykj.modbus.exception.*;
import com.jykj.modbus.manage.*;
import com.jykj.modbus.utils.ByteUtils;
import com.jykj.modbus.utils.ShowUtils;
import com.jykj.util.config.AppConfig;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import javax.annotation.Resource;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;


/**
 * 获取串口数据
 */
public class Test {

    @Resource(name= "equipmentDataService")
    public EquipmentDataService equipmentDataService;

    public EquipmentData equipmentData = new EquipmentData();
    private ReturnModBus returnModBus = new ReturnModBus();
    private static String returnData;

    public void setReturnModBus(ReturnModBus returnModBus){
        this.returnModBus = returnModBus;
    }

    public void setEquipmentData(EquipmentData equipmentData){
        this.equipmentData = equipmentData;
    }

    /**
     * 打开串口
     * 创建ReturnModBus对象,以便保存信息
     * @param evt
     * @param sensorType 设备类型
     * @param type 查询类型
     * @param obj 设备信息
     * @return
     */
    public ReturnModBus openSerialPort1(ActionEvent evt , String sensorType , String type , Equipment obj , Integer resultsDigits) {
        // 获取波特率
        int baudrate = 9600;
        baudrate = Integer.parseInt(obj.getBaudRate());
        returnModBus.setType(type);
        returnModBus.setSensorType(sensorType);
        SerialPort serialport1 = returnModBus.getSerialport();
        // 检查串口名称是否获取正确
        try {
            serialport1 = SerialPortManager.openPort(obj.getSerialPort(), baudrate , obj);
            if (serialport1 != null) {
                equipmentData.setSensorType(sensorType);
                equipmentData.setMessageType(Integer.parseInt(type));
                equipmentData.setIdentificationCode(obj.getIdentificationCode());
                equipmentData.setResultsDigits(resultsDigits);
                System.out.println("串口已打开");
            }
        } catch (SerialPortParameterFailure e) {
            e.printStackTrace();
        } catch (NotASerialPort e) {
            e.printStackTrace();
        } catch (NoSuchPort e) {
            e.printStackTrace();
        }
        catch (PortInUse e) {
            e.printStackTrace();
            ShowUtils.warningMessage("串口已被占用！");
        }
        try {
            //添加监听
            SerialPortManager.addListener(serialport1, new SerialListener());
            returnModBus.setSerialport(serialport1);
        } catch (TooManyListeners e) {
            e.printStackTrace();
        }
        return returnModBus;
    }

    /**
     * 关闭串口
     *
     * @param evt
     *
     */
    public void closeSerialPort(ActionEvent evt) {
        SerialPortManager.closePort(returnModBus.getSerialport());
        System.out.println("串口已关闭");
        returnModBus.setSerialport(null);
        returnModBus.setType(null);
        returnModBus.setReturnData(null);
    }


    private class SerialListener implements SerialPortEventListener {
        /**
         * 处理监控到的串口事件
         * 接收到串口返回的数据后将数据进行处理
         */
        @Override
        public void serialEvent(SerialPortEvent serialPortEvent) {

            switch (serialPortEvent.getEventType()) {

                case SerialPortEvent.BI: // 10 通讯中断
                        ShowUtils.errorMessage("与串口设备通讯中断");
                    break;

                case SerialPortEvent.OE: // 7 溢位（溢出）错误

                case SerialPortEvent.FE: // 9 帧错误

                case SerialPortEvent.PE: // 8 奇偶校验错误

                case SerialPortEvent.CD: // 6 载波检测

                case SerialPortEvent.CTS: // 3 清除待发送数据

                case SerialPortEvent.DSR: // 4 待发送数据准备好了

                case SerialPortEvent.RI: // 5 振铃指示

                case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
                    break;

                case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
                    byte[] data = null;
                    SerialPort serialPort = returnModBus.getSerialport();
                    try {
                        if (serialPort == null) {
                            ShowUtils.errorMessage("串口对象为空！监听失败！");
                        } else {
                            // 读取串口数据
                            data = SerialPortManager.readFromPort(serialPort);
                            System.out.println("获取到的串口数据:"+ByteUtils.byteArrayToHexString(data,
                                    true));
                            returnData = ByteUtils.byteArrayToHexString(data,
                                    true);
                            //字符串去空格
                            String hexString = returnData.replace(" ", "");
                            Map<String, Object> mapData = new HashMap<>();
                            if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.air"))){
                                equipmentData.setResultsFrame(hexString);
                            }else if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.electricity"))){
                                if (equipmentData.getResultsFrame().length() == 0){
                                    //结果长度为0
                                    equipmentData.setResultsFrame(hexString);
                                }else if (equipmentData.getResultsFrame().length() < equipmentData.getResultsDigits() ){
                                    //结果长度小于预计长度
                                    equipmentData.setResultsFrame(equipmentData.getResultsFrame()+hexString);
                                    if (equipmentData.getResultsFrame().length() == equipmentData.getResultsDigits()){
                                        //拼装后,结果长度等于预计长度
                                        break;
                                    }else if (equipmentData.getResultsFrame().length() > equipmentData.getResultsDigits()){
                                        //拼装后长度大于预计长度,需要通过起始字符及结束字符进行截取
                                        equipmentData.setResultsFrame(equipmentData.getResultsFrame().substring(equipmentData.getResultsFrame().indexOf("FE") , equipmentData.getResultsDigits()));
                                    }
                                }else if (equipmentData.getResultsFrame().length() == equipmentData.getResultsDigits()){
                                    break;
                                }else if (equipmentData.getResultsFrame().length() > equipmentData.getResultsDigits()){
                                    equipmentData.setResultsFrame(equipmentData.getResultsFrame().substring(equipmentData.getResultsFrame().indexOf("FE") , equipmentData.getResultsDigits()));
                                    break;
                                }else {
                                    break;
                                }
                            }else if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.water"))){
                                //水表
                                equipmentData.setResultsFrame(hexString);
                            }
                        }
                    } catch (Exception e) {
                        ShowUtils.errorMessage(e.toString());
                        // 发生读取错误时显示错误信息后退出系统
                        System.exit(0);
                    }
                    break;
                default:
            }
        }
    }

    public EquipmentData dataProcessingByEle(String dataStr){
        returnData = dataStr;
        //字符串去空格
        String hexString = returnData.replace(" ", "");
        Map<String, Object> mapData = new HashMap<>();
        if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.air"))){
            equipmentData.setResultsFrame(hexString);
        }else if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.electricity"))){
            if (equipmentData.getResultsFrame().length() == 0){
                //结果长度为0
                equipmentData.setResultsFrame(hexString);
                equipmentData.setJudgeNum(0);
            }else if (equipmentData.getResultsFrame().length() < equipmentData.getResultsDigits() ){
                //结果长度小于预计长度
                equipmentData.setResultsFrame(equipmentData.getResultsFrame()+hexString);
                equipmentData.setJudgeNum(0);
                if (equipmentData.getResultsFrame().length() > equipmentData.getResultsDigits()){
                    //拼装后长度大于预计长度,需要通过起始字符及结束字符进行截取
                    equipmentData.setResultsFrame(equipmentData.getResultsFrame().substring(equipmentData.getResultsFrame().indexOf("FE") , equipmentData.getResultsDigits()));
                    equipmentData.setJudgeNum(1);
                }
            }else if (equipmentData.getResultsFrame().length() > equipmentData.getResultsDigits()){
                equipmentData.setResultsFrame(equipmentData.getResultsFrame().substring(equipmentData.getResultsFrame().indexOf("FE") , equipmentData.getResultsDigits()));
                equipmentData.setJudgeNum(1);
            }
        }else if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.water"))){
            //水表
            equipmentData.setResultsFrame(hexString);
        }
        return equipmentData;
    }

    public EquipmentData dataProcessingForJserial(String dataStr){
        returnData = dataStr;
        //字符串去空格
        String hexString = returnData.replace(" ", "");
        Map<String, Object> mapData = new HashMap<>();
        if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.air"))){
            equipmentData.setResultsFrame(hexString);
        }else if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.electricity"))){
            if (equipmentData.getResultsFrame().length() == 0){
                //结果长度为0
                equipmentData.setResultsFrame(hexString);
                equipmentData.setJudgeNum(0);
            }else if (equipmentData.getResultsFrame().length() < equipmentData.getResultsDigits() ){
                //结果长度小于预计长度
                equipmentData.setResultsFrame(equipmentData.getResultsFrame()+hexString);
                equipmentData.setJudgeNum(0);
                if (equipmentData.getResultsFrame().length() > equipmentData.getResultsDigits()){
                    //拼装后长度大于预计长度,需要通过起始字符及结束字符进行截取
                    equipmentData.setResultsFrame(equipmentData.getResultsFrame().substring(equipmentData.getResultsFrame().indexOf("FE") , equipmentData.getResultsDigits()));
                    equipmentData.setJudgeNum(1);
                }
            }else if (equipmentData.getResultsFrame().length() > equipmentData.getResultsDigits()){
                equipmentData.setResultsFrame(equipmentData.getResultsFrame().substring(equipmentData.getResultsFrame().indexOf("FE") , equipmentData.getResultsDigits()));
                equipmentData.setJudgeNum(1);
            }
        }else if (returnModBus.getSensorType().equals(AppConfig.getProperty("sensor.water"))){
            //水表
            equipmentData.setResultsFrame(hexString);
        }
        return equipmentData;
    }

    /**
     * 设备返回帧数据处理,解析出需要的数据
     * @param sensorType 设备类型
     * @param messageType 查询类型
     * @param dataStr 返回字符
     * @return 组合为map
     */
    public Map<String , Object> dataProcessing(String sensorType , String messageType , String dataStr){
        Map<String, Object> mapData = new HashMap<>();
        try {
            if (sensorType.equals(AppConfig.getProperty("sensor.air"))){
                mapData = AirSensor.messageConversion(dataStr , messageType);
            }else if (sensorType.equals(AppConfig.getProperty("sensor.electricity"))){
                //mapData = DlxElectricitySensor.electricityMessageConversion(dataStr , returnModBus.getType());
                mapData = AgreementEle.analysis(dataStr);
            }else if (sensorType.equals(AppConfig.getProperty("sensor.water"))){
                mapData = WaterMeterSensor.WaterMeterMessageConversion(dataStr , messageType);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return mapData;
    }
}
